package Utilities;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * Puerto, forma parte de Ruta. Las cargas y contenedores llegan y salen 
 * de un puerto.  
 * @author francisco
 */
public class Puerto implements Serializable{
   
   //Atributos
   private String nombre, pais, coordenadas;
   private ArrayList<Contenedor> misContenedores;
   private ArrayList<Barco> misBarcos;
   private boolean consolidado;
   private static Scanner teclado=new Scanner(System.in);

    /**
    *Constructor.
    *@param nombre1 String del nombre del puerto.  
    *@param pais1 String del país del puerto. 
    *@param coordenadas1 String que representa las coordenadas, no se usan para nada.
    */
    public Puerto(String nombre1,String pais1, String coordenadas1 ){
        nombre=nombre1;
        pais=pais1;
        coordenadas=coordenadas1;
        consolidado=true;
        misContenedores=new ArrayList<Contenedor>();
        misBarcos=new ArrayList<Barco>();
     }

    /**
     * Devuelve la lista de contenedores en un puerto
     * @return misContenedores 
     */
    public ArrayList<Contenedor> getMisContenedores() {
        return misContenedores;
    }

    @Override
    /*
     * Devuelve la información del puerto y de todos los contenedores en él.
     */
    public String toString(){
     String mensaje= "\n\""+nombre+"\"";
     mensaje+="\nPaís: "+pais;
     mensaje+="\tCoordenadas: "+coordenadas;
     mensaje+="\nContenedores:\n";
     if (! misContenedores.isEmpty()){
        mensaje+=misContenedores+"\n";
     }else{
        mensaje+="No han contenedores en este puerto.";
     }
     return mensaje;
    }
    /**
     * Devuelve el nombre del puerto
     * @return nombre
     */
    public String getNombre() {
        return nombre;
    }
    /**
     * Devuelve el país del puerto.
     * @return pais
     */
    public String getPais() {
        return pais;
    }
    
    /**
     * Devuelve las coordenadas del puerto.
     * @return coordenadas
     */
    public String getCoordenadas() {
        return coordenadas;
    }
    
    /**
     * Método equals, compara el nombre y país de dos barcos. 
     * Al crear un nuevo puerto, se asegura que no haya dos con el mismo
     * nombre y país. 
     * @param puerto Puerto con el que se va a comparar.
     * @return true si son iguales. 
     * @return false si no lo son. 
     */
    public boolean equals(Puerto puerto){
        boolean nombres=nombre.equals(puerto.getNombre());
        boolean paises=pais.equals(puerto.getPais());
        if(nombres && paises)
            return true;
        else
            return false;
    }
    
    /**
     * Devuelve si el puerto está consolidado o no. 
     * Todavía es necesario implementar que no se "cargue" un barco
     *a menos que el puerto en el que se encuentre esté consolidado. 
     * @return true si están consolidadas las cargas en el puerto. 
     * @return false en caso contrario. 
     */
    public boolean isConsolidado() {
        return consolidado;
    }
    
    /**
     * Agrega el barco a la lista de barcos del puerto. 
     * @param barco Barco que llega al puerto. 
     */
    public void addBarco(Barco barco){
        misBarcos.add(barco);
    }
    
    /**
     * Elimina el barco de la lista de barcos del puerto. 
     * @param barco Barco que se fue del puerto. 
     * Actualmente para comparar se utiliza comparación por referencias
     * barco1==barco, a ver qué tal funciona. 
     */
    public void removeBarco(Barco barco){
        misBarcos.remove(barco);
    }
    
    /**
     * cuando se crea una nueva carga en el puerto, se coloca el consolidado
     * en false. 
     */
    public void agregar(){
        consolidado=false;
    }
    
    /**
     * Consolida todas las cargas en este puerto. De la listaCargas de todas las cargas
     * que no estén previamente consolidadas. 
     */
    public void consolidar(){
        consolidado=true;
        for(Carga carga:Principal.listaCargas){
        if(!(carga.isConsolidado())){
            float peso=carga.getPeso();
            carga.consolidar();
            System.out.println("Consolidando Carga: "+carga.getNombre());
            Puerto destino=carga.getDestino();
            if(misContenedores.size()>0){
                for(Contenedor elContenedor:misContenedores){
                    if(peso==0)
                        break;
                    else{
                        if(elContenedor.getEspacioLibre()>0 && elContenedor.getPuertoDestino().equals(destino)){
                            int respuesta=0;
                            do{
                                System.out.print("¿Desea usar el contenedor "+elContenedor.getNombre()+" (sí=1,no=2)?: ");
                                respuesta=Principal.ingresarInt();
                            }while(respuesta!=1 && respuesta!=2);
                            if(respuesta==1){
                                if(elContenedor.getEspacioLibre()>peso){
                                    elContenedor.agregarCarga(carga,peso);
                                    peso=0;
                                } else {
                                    float peso2=elContenedor.getEspacioLibre();
                                    peso-=peso2;
                                    elContenedor.agregarCarga(carga,peso2);
                                }
                            }
                        }
                    }
                }
            }
                float peso3=Contenedor.getCapacidad();
                while(peso>0){
                    String nombrecito;
                    boolean repetir=false;
                    do{
                        repetir=false;
                        System.out.print("Introduzca un nombre para nuevo contenedor: ");
                        nombrecito=teclado.nextLine();
                        
                       
                        for(Contenedor contenedor:Principal.listaContenedores){
                            if(nombrecito.equals(contenedor.getNombre())){
                                repetir=true;
                                System.out.println("Este contenedor ya existe");
                            }
                        }
                        
                    }while(repetir);
                    Contenedor contenedor;
                    if(peso>peso3){
                        contenedor=new Contenedor(nombrecito,this,destino,carga,peso3);
                        peso-=peso3;
                    } else {
                        contenedor=new Contenedor(nombrecito,this,destino,carga,peso);
                        peso=0;
                    }
                    misContenedores.add(contenedor);
                    Principal.listaContenedores.add(contenedor);
                }
            
        }
    }
    }
    
    /**
     * Devuelve una lista de todas las cargas que actualmente están en el puerto.
     * (puede repetirse la misma carga varias veces)
     * @return misCargas
     */
    public ArrayList<Carga> getCargasEnPuerto(){
            ArrayList<Carga> misCargas=new ArrayList<Carga>();
            for(Contenedor contenedor: misContenedores){
                for(Carga carga:contenedor.getMisCargas()){
                    misCargas.add(carga);
                }
            }
            return misCargas;
    }
    
    /**
     * Devuelve la lista que contiene los barcos que estan en un momento dado en el puerto. 
     * @return misBarcos barcos que estan en el puerto. 
     */
    public ArrayList<Barco> getBarcosEnPuerto() {
        return misBarcos;
    }
    
}
     

